package by.dvrudenko.avtobaza.services.impl;

import java.sql.Timestamp;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.persistence.metamodel.SingularAttribute;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import by.dvrudenko.avtobaza.dataaccess.UserOrderDao;
import by.dvrudenko.avtobaza.dataaccess.en.Restriction;
import by.dvrudenko.avtobaza.datamodel.Route;
import by.dvrudenko.avtobaza.datamodel.UserOrder;
import by.dvrudenko.avtobaza.datamodel.UserOrder_;
import by.dvrudenko.avtobaza.datamodel.enums.OrderStatus;
import by.dvrudenko.avtobaza.services.RouteService;
import by.dvrudenko.avtobaza.services.UserOrderService;

@Service
public class UsersOrderServiceImpl implements UserOrderService{
	private static final Logger LOGGER = LoggerFactory.getLogger(UsersOrderServiceImpl.class);
	
	@Inject
	private UserOrderDao dao;
	
	@Inject
	private RouteService daoRoute;
	
	@PostConstruct
	private void init() {
		LOGGER.info("Instance of UserOrderService is created. Class is: {}",
				getClass().getName());
	}
	
	@Override
	public UserOrder get(Long id) {
		UserOrder entity = dao.getById(id);
		return entity;
	}

	@Override
	public void saveOrUpdate(UserOrder userOrder) {
		if (userOrder.getId() == null) {
			LOGGER.debug("Save new: {order}", userOrder);
			// при создании маршрута, состояние заказа ставиться по умолчанию processed
			userOrder.setOrderStatus(OrderStatus.processed);
			dao.insert(userOrder);
		} else {
			LOGGER.debug("Update: {order}", userOrder);
			dao.update(userOrder);
		}
	}

	@Override
	public void delete(UserOrder userOrder) {
		LOGGER.debug("Remove: {order}", userOrder);
		/* сначала удаляем маршрут, находим его среди всех маршрутов по id, если он был уже
		 * удален вернется значение null
		*/ 
		Route route = daoRoute.getRouteByUserOrder(userOrder.getId());
		if (route!=null){
			LOGGER.debug("Remove: {route}", route);
			daoRoute.delete(route);
		}
		// удаляем заказ
		dao.delete(userOrder.getId());
	}

	@Override
	public void deleteAll() {
		LOGGER.debug("Remove all order");
		dao.deleteAll();
	}

	@Override
	public List<UserOrder> getAllOrderByUserId(Long id) {
		return dao.getAllByFieldRestriction(UserOrder_.user, id);
	}

	@Override
	public List<UserOrder> getAllOrderByStatus(OrderStatus orderStatus) {
		return dao.getAllActiveOrderByStatus(orderStatus);
	}

	@Override
	public List<UserOrder> getAllOrderByDate(Timestamp year, Restriction condition) {
			return dao.getAllByFieldByDate(UserOrder_.orderDate, year, condition);
	}

	@Override // установить статус груза на orderStatus
	public void changeOrderStatus(Long id, OrderStatus orderStatus) {
		if (orderStatus.equals(OrderStatus.pick_up_cargo) || (orderStatus.equals(OrderStatus.finish))){
			UserOrder userOrder = dao.getById(id);
			userOrder.setOrderStatus(orderStatus);
			dao.update(userOrder);
		}else{
			throw new IllegalArgumentException (orderStatus + " - orderStatus must be equlas pick_up_cargo or finish,"
					+ " you can't change order status to 'processed' or 'rides_for_cargo' ");	
		}
	}

	@Override
	public UserOrder getRandomOrder() {
		return dao.getRandomOrder();
	}

	@Override
	public List<UserOrder> getAllUserOrder(SingularAttribute<UserOrder, ?> attr,
			boolean ascending, int startRecord, int pageSize, Long UserId) {
		return dao.getAllUserOrders(attr, ascending, startRecord, pageSize, UserId);
	}

	@Override
	public Long getCount(Long UserId) {
		return dao.getCount(UserId);
	}
	
	

	
}
